home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-09-27 | 6.6 KB | 232 lines | [TEXT/CCL2] |
- ;;; File: expr-parser Author: John
-
- (define (parse-exp)
- (trace-parser exp
- (parse-exp-0)))
-
- (define (parse-exp-0) ;; This picks up expr type signatures
- (let ((exp (parse-exp-i)))
- (token-case
- (\:\: (let ((signature (parse-signature)))
- (make exp-sign (exp exp) (signature signature))))
- (else exp))))
-
- (define (parse-exp-i) ;; This collects a list of exps for later prec parsing
- (let ((exps (parse-infix-exps)))
- (if (null? (cdr exps))
- (car exps)
- (make pp-exp-list (exps exps)))))
-
- (define (parse-infix-exps)
- (token-case
- (- (cons (make negate) (parse-infix-exps)))
- (\\ (list (parse-lambda)))
- (|let| (list (parse-let)))
- (|if| (list (parse-if)))
- (|case| (parse-possible-app (parse-case)))
- (else (let ((aexp (parse-aexp)))
- (parse-possible-app aexp)))))
-
- (define (parse-possible-app exp)
- (token-case
- (aexp-start
- (let ((exp2 (parse-aexp)))
- (parse-possible-app (make app (fn exp) (arg exp2)))))
- (varop
- (let ((varop (varop->ast)))
- (if (eq-token? '\))
- (list exp varop)
- `(,exp ,varop ,@(parse-infix-exps)))))
- (conop
- (let ((conop (conop->ast)))
- (if (eq-token? '\))
- (list exp conop)
- `(,exp ,conop ,@(parse-infix-exps)))))
- (else (list exp))))
-
- (define (parse-lambda)
- (trace-parser lambda
- (save-parser-context
- (let ((pats (parse-apat-list)))
- (require-token -> (signal-missing-token "`->'" "lambda expression"))
- (let ((exp (parse-exp)))
- (make lambda (pats pats) (body exp)))))))
-
- (define (parse-let)
- (trace-parser let
- (save-parser-context
- (let ((decls (parse-decl-list)))
- (require-token |in| (signal-missing-token "`in'" "let expression"))
- (let ((exp (parse-exp)))
- (make let (decls decls) (body exp)))))))
-
- (define (parse-if)
- (trace-parser if
- (save-parser-context
- (let ((test-exp (parse-exp)))
- (require-token |then| (signal-missing-token "`then'" "if expression"))
- (let ((then-exp (parse-exp)))
- (require-token |else| (signal-missing-token "`else'" "if expression"))
- (let ((else-exp (parse-exp)))
- (make if (test-exp test-exp)
- (then-exp then-exp)
- (else-exp else-exp))))))))
-
- (define (parse-case)
- (trace-parser case
- (save-parser-context
- (let ((exp (parse-exp)))
- (require-token |of| (signal-missing-token "`of'" "case expression"))
- (let ((alts (start-layout (function parse-alts))))
- (make case (exp exp) (alts alts)))))))
-
- (define (parse-alts in-layout?)
- (token-case
- (pat-start
- (let ((alt (parse-alt)))
- (token-case
- (\; (cons alt (parse-alts in-layout?)))
- (else (close-layout in-layout?)
- (list alt)))))
- (else
- (close-layout in-layout?)
- '())))
-
- (define (parse-alt)
- (trace-parser alt
- (let* ((pat (parse-pat))
- (rhs-list (token-case
- (-> (let ((exp (parse-exp)))
- (list (make guarded-rhs (guard (make omitted-guard))
- (rhs exp)))))
- (\| (parse-guarded-alt-rhs))
- (else (signal-missing-token "`->' or `|'" "rhs of alt"))))
- (decls (parse-where-decls)))
- (make alt (pat pat) (rhs-list rhs-list) (where-decls decls)))))
-
- (define (parse-guarded-alt-rhs)
- (let ((guard (parse-exp)))
- (require-token -> (signal-missing-token "`->'" "alt"))
- (let* ((exp (parse-exp))
- (res (make guarded-rhs (guard guard) (rhs exp))))
- (token-case
- (\| (cons res (parse-guarded-alt-rhs)))
- (else (list res))))))
-
- (define (parse-aexp)
- (trace-parser aexp
- (token-case
- (var (save-parser-context (var->ast)))
- (con (save-parser-context (con->ast)))
- (literal (literal->ast))
- (_ (save-parser-context (make bottom)))
- (\(
- (token-case
- (\) (**con/def (core-symbol "UnitConstructor")))
- ((no-advance -) (parse-exp-or-tuple))
- (varop
- (let ((varop (varop->ast)))
- (make-right-section varop)))
- (conop
- (let ((conop (conop->ast)))
- (make-right-section conop)))
- (else
- (parse-exp-or-tuple))))
- (\[
- (token-case
- (\] (make list-exp (exps '())))
- (else
- (let ((exp (parse-exp)))
- (token-case
- (\, (let ((exp2 (parse-exp)))
- (token-case
- (\] (make list-exp (exps (list exp exp2))))
- (\.\. (token-case
- (\] (make sequence-then (from exp) (then exp2)))
- (else
- (let ((exp3 (parse-exp)))
- (require-token
- \]
- (signal-missing-token
- "`]'" "sequence expression"))
- (make sequence-then-to (from exp) (then exp2)
- (to exp3))))))
- (else
- (make list-exp
- (exps `(,exp ,exp2 ,@(parse-exp-list))))))))
- (\.\. (token-case
- (\] (make sequence (from exp)))
- (else
- (let ((exp2 (parse-exp)))
- (require-token
- \]
- (signal-missing-token "`]'" "sequence expression"))
- (make sequence-to (from exp) (to exp2))))))
- (\] (make list-exp (exps (list exp))))
- (\| (parse-list-comp exp))
- (else
- (signal-invalid-syntax
- "a list, sequence, or list comprehension")))))))
- (else
- (signal-invalid-syntax "an aexp")))))
-
- (define (make-right-section op)
- (let ((exps (parse-infix-exps)))
- (token-case
- (\) (make pp-exp-list (exps (cons op exps))))
- (else (signal-missing-token "`)'" "right section expression")))))
-
- (define (parse-exp-list)
- (token-case
- (\] '())
- (\, (let ((exp (parse-exp))) (cons exp (parse-exp-list))))
- (else (signal-missing-token "`]' or `,'" "list expression"))))
-
- (define (parse-exp-or-tuple)
- (let ((exp (parse-exp)))
- (token-case
- (\) exp) ; Note - sections ending in an op are parsed elsewhere
- (else (make-tuple-cons (cons exp (parse-tuple-exp)))))))
-
- (define (parse-tuple-exp)
- (token-case
- (\) '())
- (\, (let ((exp (parse-exp))) (cons exp (parse-tuple-exp))))
- (else (signal-missing-token
- "`)' or `,'" "tuple or parenthesized expression"))))
-
- ;;; List comprehensions
-
- ;;; Assume | has been consumed
-
- (define (parse-list-comp exp)
- (save-parser-context
- (let ((quals (parse-qual-list)))
- (make list-comp (exp exp) (quals quals)))))
-
- (define (parse-qual-list)
- (let ((qual (parse-qual)))
- (token-case
- (\, (cons qual (parse-qual-list)))
- (\] (list qual))
- (else (signal-missing-token "`]' or `,'" "list comprehension")))))
-
- (define (parse-qual)
- (trace-parser qual
- (save-parser-context
- (let* ((saved-excursion (save-scanner-state))
- (is-gen? (and (scan-pat) (eq-token? '<-))))
- (restore-excursion saved-excursion)
- (cond (is-gen?
- (let ((pat (parse-pat)))
- (advance-token) ; past the <-
- (let ((exp (parse-exp)))
- (make qual-generator (pat pat) (exp exp)))))
- (else
- (let ((exp (parse-exp)))
- (make qual-filter (exp exp)))))))))
-
- (define (make-tuple-cons args)
- (let ((tuple-con (**con/def (tuple-constructor (length args)))))
- (**app/l tuple-con args)))
-